home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Linux Cubed Series 8: LINUX Games
/
Linux Cubed Series 8 - LINUX Games.iso
/
games
/
x11
/
strategy
/
xnetbris.00
/
xnetbris
/
chris.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-09-19
|
8KB
|
317 lines
/*
This is an automated robot called chris. It randomly plays one of its cards
Copyright (C) 1995 Brendan Bartlett
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/uio.h>
#include <time.h>
#include "brisk.h"
static int server_fd;
static int numplayers;
static int play_type;
static int my_number; /* which player number this client is */
static struct card brisk;
static struct card hand[3]; /* This is an array with the current cards in this players hand */
static int get_card(int); /* reads a new card from the server */
static void play_brisk(void);
static void update_cards(void); /* some sort of change to the hand -- tell the user */
static int give_score(int, char *);
static int randnum;
int handler(int signum);
int start_client(char * hostname, int port);
void main(int, char *[]);
int handler(int signum)
{
fprintf(stderr, "got SIGPIPE, client cleaning..\n");
close(server_fd);
exit(0);
}
void main(int argc, char *argv[])
{
int port = 10000;
struct packet p;
int i;
signal(SIGPIPE, handler);
if(argc == 1)
{
printf("usage: %s <hostname> <port>\n", argv[0]);
printf(" hostname is the name where the SERVER is running.\n");
printf(" port is an optional setting to connect to the server.\n");
exit(0);
}
if(argc == 3)
port = atoi(argv[2]);
if(!start_client(argv[1], port))
{
printf("cannot connect to server '%s'\n", argv[1]);
exit(0);
}
/* Read in our hand from the server */
for(i = 0; i < 3; i++)
{
get_card(i);
printf(" %d %d \t", hand[i].suit, hand[i].weight);
}
/* Read in the brisk from the server */
read(server_fd, &p, sizeof(struct packet));
if(p.type != MOVE_TYPE || p.data.move.player != 5)
{
fprintf(stderr, "server did not send the brisk card!\n");
exit(0);
}
memcpy(&brisk, &p.data.move.play_card, sizeof(struct card));
printf("\nbrisk: %d %d\n", brisk.suit, brisk.weight);
printf("\n");
play_brisk();
}
/*
* This routine will read from the server for a packet of MOVE_TYPE (or DEAL_TYPE) and will fill in the
* given card in the hand[] array.
*
* If the packet is of type DEAL_TYPE, the argument 'card' is ignored and the suggested value in the
* packet is used instead.
*
* Returns 0 on failure
* 1 on success
*/
static int get_card(int card)
{
struct packet p;
read(server_fd, &p, sizeof(struct packet));
if( (p.type != MOVE_TYPE) && (p.type != DEAL_TYPE) )
{
fprintf(stderr, "FATAL ERROR: MOVE_TYPE or DEAL_TYPE expected!\n");
return 0;
}
if(p.type == DEAL_TYPE)
memcpy(&hand[p.data.deal.rec_place], &p.data.deal.deal_card, sizeof(struct card));
else
memcpy(&hand[card], &p.data.move.play_card, sizeof(struct card));
return 1;
}
/* *
* This updates the cards that the user sees on the scren.
*
*/
static void update_cards(void)
{
int i;
for(i = 0; i < 3; i++)
printf("%d %d \t", hand[i].suit, hand[i].weight);
printf("\n");
}
static void play_brisk(void)
{
struct packet in, out;
srand(time(NULL));
while(1)
{
read(server_fd, &in, sizeof(struct packet));
switch(in.type)
{
case LAST_HAND:
printf("Entering the last 3 hands..\n");
break;
case END_GAME:
printf("That's the end of the game!\n");
printf("Final Scores: %d for you, %d for the other %s\n",
give_score(0, in.data.score.scores),
give_score(1, in.data.score.scores), (play_type == CHAOS) ? "player" : "team");
close(server_fd);
exit(0);
case MESSAGE_TYPE:
printf("message: [%s]\n", in.data.message.string);
break;
case MOVE_TYPE:
printf("player %d played card %d %d\n", in.data.move.player, in.data.move.play_card.suit, in.data.move.play_card.weight);
break;
case SCORE_UPDATE:
printf("\nplayer %d won last hand!\n", in.data.score.lastwin);
printf("scores: %d %d\n", in.data.score.scores[0], in.data.score.scores[1]);
in.type = OK;
write(server_fd, &in, sizeof(struct packet));
break;
case DEAL_TYPE:
memcpy(&hand[in.data.deal.rec_place], &in.data.deal.deal_card, sizeof(struct card));
break;
case INFORM_TYPE:
printf("server send INFORM_TYPE. Not at start of game\n");
break;
case MOVE_EXPECTED:
if(in.data.move.player != my_number)
break;
out.type = MOVE_TYPE;
out.data.move.player = my_number;
do
{
/* Chris randomly chooses a card from his hand.
* In the final two hands a player has less then the normal
* three cards, so a -1 is used to repersent the non-existant card.
* Chris checks for it and tries again if he chooses it.
*/
while(1)
{
randnum = rand() % 3;
if ((hand[randnum].suit != -1) && (hand[randnum].weight != -1))
{
out.data.move.play_card.suit = hand[randnum].suit;
out.data.move.play_card.weight = hand[randnum].weight;
printf("%d %d\n", hand[randnum].suit, hand[randnum].weight);
break;
}
}
write(server_fd, &out, sizeof(struct packet));
read(server_fd, &in, sizeof(struct packet));
if(in.type == ILLEGAL_MOVE)
printf("illegal card %d %d\n", out.data.move.play_card.suit, out.data.move.play_card.weight);
}
while(in.type == ILLEGAL_MOVE);
hand[in.data.ok.cardpos].suit = -1;
hand[in.data.ok.cardpos].weight = -1;
}
}
}
/*
* Given the packet 'p' return the score of 'who', where
* who is 0 for yourself and 1 for the other player/team
*/
static int give_score(int who, char *scores)
{
char scoretab[] = { 0, 1, 0, 1 };
if(who == 0)
return scores[scoretab[my_number]];
else
return scores[! scoretab[my_number]];
}
int start_client(char *hostname, int port)
{
struct sockaddr_in addr;
struct protoent *proto;
struct hostent *host;
struct packet p;
proto = getprotobyname("tcp");
if(!proto)
{
printf("tcp not supported here.\n");
return 0;
}
host = gethostbyname(hostname);
if(!host)
{
printf("cannot find host '%s'\n", host);
return 0;
}
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = inet_addr(hostname);
memcpy((char *)&addr.sin_addr, (char *)(*host->h_addr_list), host->h_length);
server_fd = socket(PF_INET, SOCK_STREAM, proto->p_proto);
if(server_fd == -1)
{
perror("socket");
return 0;
}
printf("Attemping to connect to port %i of server %s.\n", port, hostname);
if(connect(server_fd, (struct sockaddr *)&addr, sizeof(addr)) == -1)
{
perror("connect");
return 0;
}
read(server_fd, &p, sizeof(struct packet));
printf("# players %d (robot:Chris). I am player # %d\n", p.data.inform.numplayers, p.data.inform.yournumber);
numplayers = p.data.inform.numplayers;
play_type = p.data.inform.play_type;
my_number = p.data.inform.yournumber;
return 1;
}